<?php

namespace App\Listeners;

use App\Constant\QueueKey;
use App\Constant\NewFlowEnum;
use App\Constants\RedisKey;
use App\Events\LoanRequestApplyEvent;
use App\Events\NewFlowOrderEvent;
use App\Facades\MoneyPlatformRequestFacade;
use App\Facades\SamLogFacade;
use App\Models\LoanRequestFailedLog;
use App\Models\User;
use App\Models\UserApplyRiskLog;
use App\Models\UserCertOcr;
use App\Models\UserDeviceInfo;
use App\Models\UserLoanRequest;
use Carbon\Carbon;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class LoanRequestApplyEventListener implements ShouldQueue
{
    use InteractsWithQueue;
    public $queue = QueueKey::QUEUE_LOAN_REQUEST_APPLY;
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Description:发起授信申请
     * Author: Sam
     * DateTime: 2019-03-27 19:45
     * @param LoanRequestApplyEvent $event
     * @return bool
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function handle(LoanRequestApplyEvent $event)
    {
        $loan = UserLoanRequest::find($event->loan->id);
        try{
            $pid = getmypid();
            $redis_key = sprintf(RedisKey::LOAN_APPLY_LISTENER_KEY, $loan->id);
            if($loan->retry!=UserLoanRequest::RETRY_YES){ //不是隔天重试的数据才处理
                $lock =  Redis::get($redis_key);
                if($lock){
                    SamLogFacade::debug("进程【{$pid}】处理申请授信【{$loan->id}】失败：进程【{$lock}】正在处理该授信");
                    return false;
                }
            }
            //加锁
            Redis::setex($redis_key,30,$pid);
            if($loan->status == UserLoanRequest::STATUS_WAIT_FOR_RISK||$loan->retry == UserLoanRequest::RETRY_YES ){ //&& $loan->retry_date == Carbon::now()->toDateString()
                $user = User::find($loan->user_id);
                $age = $user->age;
                $marry_status = $user->marry_status;
                $purpose = $loan->use;
                if($age>35&&$loan->use=='02'){
                    $purpose = '04';
                }
                if($marry_status=='1'&&$loan->use=='03'){
                    $purpose = '08';
                }
                $device_info = UserDeviceInfo::where('loan_request_id', $loan->id)
                    ->select(['ip', 'gps', 'device_type', 'device', 'device_os', 'device_mac', 'device_imei', 'device_uuid'])
                    ->first();
                $actually_loan_money = $loan->actually_loan_money / 100;
                if($actually_loan_money <= 5000){
                    $period = 3;
                }else{
                    $period = $loan->period;
                }
                $apply_data = [
                    'outCreditId' => $loan->trans_id,
                    'nfsp_user_id' => $user->nfsp_user_id,
                    'amount' => $actually_loan_money,
                    'period' => $period,
                    'purpose' => $purpose,
                    'deviceIP' => $device_info->ip,
                    'deviceGPS' => $device_info->gps,
                    'deviceType' => $device_info->device_type,
                    'device' => $device_info->device,
                    'deviceOS' => $device_info->device_os,
                    'deviceMac' => $device_info->device_mac,
                    'deviceIMEI' => $device_info->device_imei ?: $device_info->device_uuid,
                ];
                $apply_data['riskId'] = UserApplyRiskLog::where('loan_request_id',$loan->id)->value('risk_id');
                SamLogFacade::debug("进程【{$pid}】处理申请授信数据：".json_encode($apply_data,JSON_UNESCAPED_UNICODE));
                if($loan->status !== 9 && $loan->risk_status !== 1){
                    Log::debug('申请授信错误-非9和1');
                    return '';
                }
                $upload_sign = false;
                $ocrs = UserCertOcr::where('user_id', $loan->user_id)->get();
                foreach ($ocrs as $k => $v){
                    if(!empty($v->upload)){
                        $upload_sign = true;
                        break;
                    }
                }
                if($upload_sign===false){
                    Log::debug('申请授信错误-身份证照片未上传ftp');
                    return '';
                }
                $apply_res = MoneyPlatformRequestFacade::loanApply($apply_data);
                event(new NewFlowOrderEvent(NewFlowEnum::NewFlowLoanAuthorize, $loan));
                if ($apply_res['code'] == '01') {
                    $loan->credit_id = $apply_res['data']['creditId'];
                    $loan->status = UserLoanRequest::STATUS_APPLY;
                    if($loan->retry == UserLoanRequest::RETRY_YES){
                        $loan->retry = UserLoanRequest::RETRY_ED;
                        if($loan->auto_loan_apply == UserLoanRequest::AUTO_LOAN_APPLY_YES){
                            Log::debug('重试自动放款之前重新授信成功,loanId:' . $loan->id);
                            $loan->auto_loan_apply = UserLoanRequest::AUTO_LOAN_APPLY_REQUEST;
                        }
                    }
                    $loan->save();
                    SamLogFacade::debug("进程【{$pid}】处理授信【{$loan->id}】申请成功");
                } else {
                    $apply_data['message'] = $apply_res['message'];
                    $apply_data['code'] = $apply_res['code'];
                $loan->status =  UserLoanRequest::STATUS_LACK_INFO;
                    $loan->save();
                    $apply_data['loan_request_id'] = $loan->id;
//                $exist = LoanRequestFailedLog::where('loan_request_id',$loan->id)->value('id');
//                if(!$exist){
                    LoanRequestFailedLog::create($apply_data);
//                }
                    SamLogFacade::debug("进程【{$pid}】处理授信【{$loan->id}】申请失败：{$apply_res['message']}");
                }
            }
            $lock = Redis::get($redis_key);
            SamLogFacade::debug("处理的PID【{$pid},加锁的PID【{$lock}】");
            //解锁
            if($pid == $lock){
                Redis::del($redis_key);
            }
        }catch(\Exception $e){
            SamLogFacade::debug("处理授信申请失败:{$e->getMessage()}，行数{$e->getLine()}");
        }

    }
}
